home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume17 / hill < prev    next >
Encoding:
Internet Message Format  |  1989-02-08  |  12.5 KB

  1. Subject:  v17i092:  Encrypt using Hill cipher
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: John Cowan <magpie.MASA.COM!cowan>
  6. Posting-number: Volume 17, Issue 92
  7. Archive-name: hill
  8.  
  9. Hill provides file encryption using the Hill cipher.  In encryption mode,
  10. plaintext is read from the standard input and ciphertext is written to the
  11. standard output in accordance with a user-specified key.  Additional
  12. options allow compressing the plaintext and/or expressing the ciphertext
  13. in ASCII.  In decryption mode, the operations of encryption mode are
  14. reversed (provided the right key is supplied).
  15.  
  16. #! /bin/sh
  17. # This is a shell archive, meaning:
  18. # 1. Remove everything above the #! /bin/sh line.
  19. # 2. Save the resulting text in a file.
  20. # 3. Execute the file with /bin/sh (not csh) to create the files:
  21. #    README
  22. #    hill
  23. #    hill.1
  24. #    hill0.c
  25. #    kappa.c
  26. #    makefile
  27. #    table.i
  28. export PATH; PATH=/bin:$PATH
  29. if test -f 'README'
  30. then
  31.     echo shar: will not over-write existing file "'README'"
  32. else
  33. sed 's/^X//' << \SHAR_EOF > 'README'
  34. ^Xhill - encryption program using Hill cipher
  35. ^X
  36. ^XHill provides file encryption using the Hill cipher.
  37. ^XIn encryption mode, plaintext is read from the standard input
  38. ^Xand ciphertext is written to the standard output
  39. ^Xin accordance with a user-specified key.
  40. ^XAdditional options allow compressing the plaintext
  41. ^Xand/or expressing the ciphertext in ASCII.
  42. ^XIn decryption mode, the operations of encryption mode
  43. ^Xare reversed (provided the right key is supplied).
  44. SHAR_EOF
  45. fi # end of overwriting check
  46. if test -f 'hill'
  47. then
  48.     echo shar: will not over-write existing file "'hill'"
  49. else
  50. sed 's/^X//' << \SHAR_EOF > 'hill'
  51. ^X# Hill interface routine
  52. ^Xcd /tmp
  53. ^XTEMP=hill$$
  54. ^XSED="sed s#junk#${TEMP}#"
  55. ^Xtrap 'rm -f ${TEMP}*' 0 1 2 3
  56. ^X# parse arguments
  57. ^Xset -- `getopt cCpsued $*`
  58. ^Xif [ $? != 0 ]
  59. ^Xthen
  60. ^X    echo "usage: $0 { -e | -d } [ { -c | -C | -p } ] [ -u ] [ key ]"
  61. ^X    exit 1
  62. ^Xfi
  63. ^X# set internal flags
  64. ^Xfor i in $*
  65. ^Xdo
  66. ^X    case $i in
  67. ^X    -c | -C | -p)    REDUCTION=$i;    shift;;
  68. ^X    -e | -d)        MODE=$i;    shift;;
  69. ^X    -u)            UU=$i;        shift;;
  70. ^X    --)            shift;        break;;
  71. ^X    esac
  72. ^Xdone
  73. ^Xif [ x$MODE = x ]
  74. ^Xthen
  75. ^X    echo "$0: must specify -e to encode or -d to decode"
  76. ^X    exit 1
  77. ^Xfi
  78. ^Xif [ x$1 = x ]
  79. ^Xthen
  80. ^X    HILL="hill0 $MODE"
  81. ^Xelse
  82. ^X    HILL="hill0 $MODE \"$1\""
  83. ^Xfi
  84. ^X# do the work
  85. ^Xif [ $MODE = -e ]
  86. ^Xthen
  87. ^X    case ${REDUCTION}${UU} in
  88. ^X    -c-u)    compact | $HILL >$TEMP
  89. ^X        uuencode $TEMP $TEMP.uu junk
  90. ^X        cat $TEMP.uu;;
  91. ^X    -c)    compact | $HILL;;
  92. ^X    -C-u)    compress | $HILL >$TEMP
  93. ^X        uuencode $TEMP $TEMP.uu junk
  94. ^X        cat $TEMP.uu;;
  95. ^X    -C)    compress | $HILL;;
  96. ^X    -p-u)    cat >$TEMP
  97. ^X        pack $TEMP >/dev/null
  98. ^X        $HILL <$TEMP.z >$TEMP
  99. ^X        uuencode $TEMP $TEMP.uu junk
  100. ^X        cat $TEMP.uu;;
  101. ^X    -p)    cat >$TEMP
  102. ^X        pack $TEMP >/dev/null
  103. ^X        $HILL <$TEMP.z;;
  104. ^X    -u)    $HILL >$TEMP
  105. ^X        uuencode $TEMP $TEMP.uu junk
  106. ^X        cat $TEMP.uu;;
  107. ^X    *)    $HILL;;
  108. ^X    esac
  109. ^Xelse
  110. ^X    case ${REDUCTION}${UU} in
  111. ^X    -c-u)    $SED | uudecode
  112. ^X        $HILL <$TEMP | uncompact;;
  113. ^X    -c)    $HILL | uncompact;;
  114. ^X    -C-u)    $SED | uudecode;
  115. ^X        $HILL <$TEMP | uncompress;;
  116. ^X    -C)    $HILL | uncompress;;
  117. ^X    -p-u)    $SED | uudecode
  118. ^X        $HILL <$TEMP >$TEMP.z
  119. ^X        rm -f $TEMP
  120. ^X        unpack $TEMP.z >/dev/null
  121. ^X        cat $TEMP;;
  122. ^X    -p)    $HILL >$TEMP.z
  123. ^X        unpack $TEMP.z >/dev/null
  124. ^X        cat $TEMP;;
  125. ^X    -u)    $SED | uudecode
  126. ^X        $HILL <$TEMP;;
  127. ^X    *)    $HILL;;
  128. ^X    esac
  129. ^Xfi
  130. SHAR_EOF
  131. fi # end of overwriting check
  132. if test -f 'hill.1'
  133. then
  134.     echo shar: will not over-write existing file "'hill.1'"
  135. else
  136. sed 's/^X//' << \SHAR_EOF > 'hill.1'
  137. ^X.TH HILL 1
  138. ^X.SH NAME
  139. ^Xhill \- encryption program using Hill cipher
  140. ^X.SH SYNOPSIS
  141. ^X.B hill
  142. ^X[ -e | -d ]
  143. ^X[ -c | -C | -p ]
  144. ^X[ -u ]
  145. ^X[ key ]
  146. ^X.SH DESCRIPTION
  147. ^X.I Hill
  148. ^Xprovides file encryption using the Hill cipher.
  149. ^XIn encryption mode,
  150. ^Xplaintext is read from the standard input
  151. ^Xand ciphertext is written to the standard output
  152. ^Xin accordance with a user-specified
  153. ^X.B key.
  154. ^XAdditional options allow compressing the plaintext
  155. ^Xand/or expressing the ciphertext in ASCII.
  156. ^XIn decryption mode, the operations of encryption mode
  157. ^Xare reversed (provided the right
  158. ^X.B key
  159. ^Xis supplied).
  160. ^X.SH OPTIONS
  161. ^X.TP
  162. ^X.B \-e
  163. ^XEncryption mode.
  164. ^X.TP
  165. ^X.B \-d
  166. ^XDecryption mode.
  167. ^X.TP
  168. ^X.B \-c
  169. ^XUse
  170. ^X.I compact
  171. ^Xor
  172. ^X.I uncompact
  173. ^Xfor compression or decompression
  174. ^X(these programs must be on the search path
  175. ^Xto use this option).
  176. ^X.TP
  177. ^X.B \-C
  178. ^XUse
  179. ^X.I compress
  180. ^Xor
  181. ^X.I uncompress
  182. ^Xfor compression or decompression
  183. ^X(these programs must be on the search path
  184. ^Xto use this option).
  185. ^X.TP
  186. ^X.B \-p
  187. ^XUse
  188. ^X.I pack
  189. ^Xor
  190. ^X.I unpack
  191. ^Xfor compression or decompression
  192. ^X(these programs must be on the search path
  193. ^Xto use this option).
  194. ^X.TP
  195. ^X.B \-u
  196. ^XUse
  197. ^X.I uuencode
  198. ^Xafter encryption
  199. ^Xor
  200. ^X.I uudecode
  201. ^Xbefore decryption
  202. ^X(these programs must be on the search path
  203. ^Xto use this option).
  204. ^X.SH "SECURITY CONSIDERATIONS"
  205. ^X.I Hill
  206. ^Xprovides strong security against straight cryptanalysis
  207. ^Xand acceptable security against probable-plaintext analysis.
  208. ^XUse of the -c and -C options
  209. ^Xactually improves security;
  210. ^Xone of these options should be used
  211. ^Xexcept where time is critical.
  212. ^XUse of the -p option
  213. ^Xdecreases security;
  214. ^Xit should be used only where space is critical
  215. ^Xand neither -C nor -c is available.
  216. ^X.PP
  217. ^XKeys must be at least 9 bytes long
  218. ^X(the maximum length is 256 bytes)
  219. ^Xand should be both long and hard to guess.
  220. ^XAll security resides in the keys.
  221. ^X.SH "TIME CONSIDERATIONS"
  222. ^X.I Hill
  223. ^Xencrypts at the rate of about 2 kilobytes per second
  224. ^X(using a 16-byte key)
  225. ^Xon an 8MHz IBM PC/AT running SCO Xenix.
  226. ^XTime increases linearly in the length of the file
  227. ^Xand in the square root of the key length.
  228. ^X.SH "SPACE CONSIDERATIONS"
  229. ^XEncrypted files increase in length by about 1%.
  230. ^X.SH FILES
  231. ^X/usr/bin/hill            script for pre/postprocessing
  232. ^X.br
  233. ^X/usr/bin/hill0            actual encryption program
  234. ^X.br
  235. ^XThese two files can be installed anywhere on the search path.
  236. ^X.SH "MS-DOS VERSION"
  237. ^XThe MS-DOS version of
  238. ^X.I hill
  239. ^Xhas the same capabilities,
  240. ^Xexcept that only the
  241. ^X.B \-e
  242. ^Xand 
  243. ^X.B \-d
  244. ^Xoptions are supported.
  245. ^X.SH "SEE ALSO"
  246. ^X.IR pack (1),
  247. ^X.IR compact (1),
  248. ^X.IR compress (1) 
  249. SHAR_EOF
  250. fi # end of overwriting check
  251. if test -f 'hill0.c'
  252. then
  253.     echo shar: will not over-write existing file "'hill0.c'"
  254. else
  255. sed 's/^X//' << \SHAR_EOF > 'hill0.c'
  256. ^X# include <stdio.h>
  257. ^X# include "table.i"
  258. ^X# ifdef DOS
  259. ^X# include <fcntl.h>
  260. ^X# include <io.h>
  261. ^X# endif
  262. ^X
  263. ^X# ifdef DOS
  264. ^X# define TTY "con"
  265. ^X# else
  266. ^X# define TTY "/dev/tty"
  267. ^X# endif
  268. ^X
  269. ^X# define Over(x) for (x = 0; x < order; x++)
  270. ^X# define Times(a,b) ((long)(a) * (long)(b) % 257)
  271. ^X
  272. ^Xint mode;
  273. ^X
  274. ^Xchar key[256];
  275. ^Xint matkey[16][16];
  276. ^Xint invec[16];
  277. ^Xint outvec[16];
  278. ^Xint order;
  279. ^X
  280. ^X
  281. ^Xsetup(argc, argv)
  282. ^Xint argc; char **argv;
  283. ^X    {
  284. ^X    FILE *tty;
  285. ^X
  286. ^X    if (strcmp(argv[1], "-e") == 0)
  287. ^X        mode = 'e';
  288. ^X    else if (strcmp(argv[1], "-d") == 0)
  289. ^X        mode = 'd';
  290. ^X    else {
  291. ^X        fprintf(stderr, "usage: hill -e [key]\n   or: hill -d [key]\n");
  292. ^X        exit(1);
  293. ^X        }
  294. ^X    if (argc > 2)
  295. ^X        strcpy(key, argv[2]);
  296. ^X    else {
  297. ^X        tty = fopen(TTY, "r+");
  298. ^X        setbuf(tty, NULL);
  299. ^X        fprintf(tty, "Key? ");
  300. ^X        fgets(key, sizeof(key), tty);
  301. ^X        key[strlen(key) - 1] = 0;
  302. ^X        fclose(tty);
  303. ^X        }
  304. ^X    }
  305. ^X
  306. ^Xmakemat()
  307. ^X    {
  308. ^X    int i, j, k;
  309. ^X    int n = 0;
  310. ^X    FILE *tty;
  311. ^X
  312. ^X    setorder();
  313. ^X    Over(i) Over(j)
  314. ^X        matkey[i][j] = key[n++];
  315. ^X    for (i = 0; i < strlen(key); i++)
  316. ^X        key[i] = 0;
  317. ^X    square();
  318. ^X    while ((k = invert()) != EOF)
  319. ^X        matkey[k][k] = (matkey[k][k] + 1) % 257;
  320. ^X    }
  321. ^X
  322. ^Xsetorder()
  323. ^X    {
  324. ^X    int n = strlen(key);
  325. ^X
  326. ^X    for (order = 0; order < 17; order++)
  327. ^X        if (order*order > n) break;
  328. ^X    order--;
  329. ^X    if (order < 3) {
  330. ^X        fprintf(stderr, "key size < 9\n");
  331. ^X        exit(1);
  332. ^X        }
  333. ^X    }
  334. ^X
  335. ^Xsquare()
  336. ^X    {
  337. ^X    int result[16][16];
  338. ^X    int i, j, k;
  339. ^X
  340. ^X    Over(i) Over(j)
  341. ^X        result[i][j] = 0;
  342. ^X    Over(i) Over(j) Over(k)
  343. ^X        result[i][j] += Times(matkey[i][k], matkey[k][j]);
  344. ^X    Over(i) Over(j)
  345. ^X        matkey[i][j] = result[i][j] % 257;
  346. ^X    }
  347. ^X
  348. ^Xint invert()
  349. ^X    {
  350. ^X    int matrix[16][16];
  351. ^X    int inverse[16][16];
  352. ^X    int i, j, k;
  353. ^X    int t;
  354. ^X    int pivot;
  355. ^X
  356. ^X    Over(i) Over(j) {
  357. ^X        matrix[i][j] = matkey[i][j];
  358. ^X        inverse[i][j] = 0;
  359. ^X        }
  360. ^X    Over(k)
  361. ^X        inverse[k][k] = 1;
  362. ^X
  363. ^X    Over(k) {
  364. ^X        if (matrix[k][k] == 0) {
  365. ^X            for (i = k + 1; i < order; i++)
  366. ^X                if (matrix[i][k]) {
  367. ^X                    Over(j) {
  368. ^X                        t = matrix[i][j];
  369. ^X                        matrix[i][j] = matrix[k][j];
  370. ^X                        matrix[k][j] = t;
  371. ^X                        t = inverse[i][j];
  372. ^X                        inverse[i][j] = inverse[k][j];
  373. ^X                        inverse[k][j] = t;
  374. ^X                        }
  375. ^X                    break;
  376. ^X                    }
  377. ^X            if (i == order) return(k);
  378. ^X            }
  379. ^X
  380. ^X        pivot = inverses[matrix[k][k]];
  381. ^X        Over(j) {
  382. ^X            matrix[k][j] = Times(matrix[k][j], pivot);
  383. ^X            inverse[k][j] = Times(inverse[k][j], pivot);
  384. ^X            }
  385. ^X        Over(i) if (i != k) {
  386. ^X            pivot = matrix[i][k];
  387. ^X            Over(j) {
  388. ^X                matrix[i][j] -= Times(pivot, matrix[k][j]);
  389. ^X                if (matrix[i][j] < 0) matrix[i][j] += 257;
  390. ^X                inverse[i][j] -= Times(pivot, inverse[k][j]);
  391. ^X                if (inverse[i][j] < 0) inverse[i][j] += 257;
  392. ^X                }
  393. ^X            }
  394. ^X        }
  395. ^X
  396. ^X    if (mode == 'd') Over(i) Over(j)
  397. ^X        matkey[i][j] = inverse[i][j];
  398. ^X    return(EOF);
  399. ^X    }
  400. ^X
  401. ^X
  402. ^Xint getvec()
  403. ^X    {
  404. ^X    int i;
  405. ^X    int padf = 0;
  406. ^X
  407. ^X    Over(i)
  408. ^X        if ((invec[i] = getchar()) == EOF) {
  409. ^X            if (i == 0) return(0);
  410. ^X            else if (padf) invec[i] = rand() % 257;
  411. ^X            else { invec[i] = 256; padf++; }
  412. ^X            }
  413. ^X        else if (invec[i] == 255 && mode == 'd')
  414. ^X            invec[i] += getchar();
  415. ^X    return(i);
  416. ^X    }
  417. ^X
  418. ^Xputvec()
  419. ^X    {
  420. ^X    int j;
  421. ^X
  422. ^X    Over(j)
  423. ^X        switch(outvec[j]) {
  424. ^X        case 256:
  425. ^X            if (mode == 'd') return;
  426. ^X            else putchar(255), putchar(1);
  427. ^X            break;
  428. ^X        case 255:
  429. ^X            putchar(255);
  430. ^X            if (mode == 'e') putchar(0);
  431. ^X            break;
  432. ^X        default:
  433. ^X            putchar(outvec[j]);
  434. ^X            }
  435. ^X    }
  436. ^X
  437. ^Xmatmul()
  438. ^X    {
  439. ^X    int i, j, k;
  440. ^X
  441. ^X    Over(i) {
  442. ^X        outvec[i] = 0;
  443. ^X        Over(j)
  444. ^X            outvec[i] += Times(invec[j], matkey[i][j]);
  445. ^X        outvec[i] %= 257;
  446. ^X        }
  447. ^X    }
  448. ^X
  449. ^Xmain(argc, argv)
  450. ^Xint argc; char **argv;
  451. ^X    {
  452. ^X    long tloc;
  453. ^X
  454. ^X# ifdef DOS
  455. ^X;setmode(fileno(stdin), O_BINARY);
  456. ^X    setmode(fileno(stdout), O_BINARY);
  457. ^X# endif
  458. ^X    time(&tloc);
  459. ^X    srand((int) tloc);
  460. ^X    setup(argc, argv);
  461. ^X    makemat();
  462. ^X    while(getvec()) {
  463. ^X;    matmul();
  464. ^X;    putvec();
  465. ^X;;}
  466. ^X    }
  467. SHAR_EOF
  468. fi # end of overwriting check
  469. if test -f 'kappa.c'
  470. then
  471.     echo shar: will not over-write existing file "'kappa.c'"
  472. else
  473. sed 's/^X//' << \SHAR_EOF > 'kappa.c'
  474. ^X/* Kappa: utility program
  475. ^X    Prints a table of character frequencies drawn from stdin.
  476. ^X;The table appears in natural order.
  477. ^X;Frequencies are per 1000 characters.
  478. ^X*/
  479. ^X
  480. ^X# include <stdio.h>
  481. ^X
  482. ^Xlong table[256];
  483. ^Xlong total;
  484. ^X
  485. ^Xmain()
  486. ^X    {
  487. ^X;int ch;
  488. ^X    int i;
  489. ^X    int lcmpr();
  490. ^X
  491. ^X    while ((ch = getchar()) != EOF) {
  492. ^X;;table[ch]++;
  493. ^X        total++;
  494. ^X        }
  495. ^X    printf("Total: %ld\n\n", total);
  496. ^X    for (i = 0; i < 256; i++) {
  497. ^X;;table[i] *= 1000;
  498. ^X        table[i] /= total;
  499. ^X        }
  500. ^X    for (i = 0; i < 256; i++) {
  501. ^X;;printf("%3.3ld ", table[i]);
  502. ^X        if ((i + 1) % 16 == 0) putchar('\n');
  503. ^X        if ((i + 1) % 128 == 0) putchar('\n');
  504. ^X        }
  505. ^X    }
  506. SHAR_EOF
  507. fi # end of overwriting check
  508. if test -f 'makefile'
  509. then
  510.     echo shar: will not over-write existing file "'makefile'"
  511. else
  512. sed 's/^X//' << \SHAR_EOF > 'makefile'
  513. ^Xall: hill0 hill.exe kappa
  514. ^Xhill0: hill0.c table.i
  515. ^X    cc -o hill0 hill0.c
  516. ^Xhill.exe: hill0.c table.i
  517. ^X    cc -DDOS -dos -o hill.exe hill0.c
  518. ^Xkappa: kappa.c
  519. ^Xinstall: hill hill0
  520. ^X    mv hill hill0 /usr/lbin
  521. SHAR_EOF
  522. fi # end of overwriting check
  523. if test -f 'table.i'
  524. then
  525.     echo shar: will not over-write existing file "'table.i'"
  526. else
  527. sed 's/^X//' << \SHAR_EOF > 'table.i'
  528. ^Xint inverses[257] = { 0, 1, 129, 86, 193, 103, 43, 147, 225, 200, 180, 187, 
  529. ^X150, 178, 202, 120, 241, 121, 100, 230, 90, 49, 222, 190, 75, 72, 89, 238, 101, 
  530. ^X195, 60, 199, 249, 148, 189, 235, 50, 132, 115, 145, 45, 163, 153, 6, 111, 40, 
  531. ^X95, 175, 166, 21, 36, 126, 173, 97, 119, 243, 179, 248, 226, 61, 30, 59, 228, 
  532. ^X102, 253, 87, 74, 234, 223, 149, 246, 181, 25, 169, 66, 24, 186, 247, 201, 244, 
  533. ^X151, 165, 210, 96, 205, 127, 3, 65, 184, 26, 20, 209, 176, 152, 216, 46, 83, 
  534. ^X53, 139, 135, 18, 28, 63, 5, 215, 164, 177, 245, 188, 224, 250, 44, 218, 116, 
  535. ^X124, 38, 113, 134, 159, 54, 15, 17, 158, 140, 114, 220, 51, 85, 255, 2, 172, 
  536. ^X206, 37, 143, 117, 99, 240, 242, 203, 98, 123, 144, 219, 133, 141, 39, 213, 7, 
  537. ^X33, 69, 12, 80, 93, 42, 252, 194, 229, 239, 122, 118, 204, 174, 211, 41, 105, 
  538. ^X81, 48, 237, 231, 73, 192, 254, 130, 52, 161, 47, 92, 106, 13, 56, 10, 71, 233, 
  539. ^X191, 88, 232, 76, 11, 108, 34, 23, 183, 170, 4, 155, 29, 198, 227, 196, 31, 9, 
  540. ^X78, 14, 138, 160, 84, 131, 221, 236, 91, 82, 162, 217, 146, 251, 104, 94, 212, 
  541. ^X112, 142, 125, 207, 22, 68, 109, 8, 58, 197, 62, 156, 19, 168, 185, 182, 67, 
  542. ^X35, 208, 167, 27, 157, 136, 16, 137, 55, 79, 107, 70, 77, 57, 32, 110, 214, 
  543. ^X154, 64, 171, 128, 256};
  544. SHAR_EOF
  545. fi # end of overwriting check
  546. #    End of shell archive
  547. exit 0
  548.  
  549.